package cn.zhfeat.framework.shiro.base;

import cn.zhfeat.framework.shiro.base.RedisCache;
import cn.zhfeat.utils.cache.CacheUtility;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


/**
 * @author ZhangHao
 * @version 1.0.0.1
 * @description: 自己redis的RedisCacheManager存储实现类
 * <p>
 * 基于cache DB缓存的session共享
 * 即使用cacheDB存取session信息，应用服务器接受新请求将session信息保存在cache DB中，当应用服务器发生故障时，
 * web服务器（apache/nginx）会遍历寻找可用节点，分发请求，当应用服务器发现session不在本机内存 时，
 * 则去cache DB中查找，如果找到则复制到本机，这样实现session共享和高可用。
 * @date 2018年5月14日 上午11:17:36
 */
public class RedisCacheManager implements CacheManager {

    private static final Logger logger = LoggerFactory
            .getLogger(RedisCacheManager.class);

    // fast lookup by name map
    private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();

    @Autowired
    private CacheUtility cacheUtility;

    @Override
    public <K, V> Cache<K, V> getCache(String name) throws CacheException {
        logger.debug("获取名称为: " + name + " 的RedisCache实例");
        Cache c = caches.get(name);

        if (c == null) {
            // create a new cache instance
            c = new RedisCache<K, V>(cacheUtility);
            // add it to the cache collection
            caches.put(name, c);
        }
        return c;
    }
}

